package top.misspro.valheimadminsocket.factory;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import top.misspro.valheimadminsocket.annotation.Action;
import top.misspro.valheimadminsocket.annotation.Handler;
import top.misspro.valheimadminsocket.exception.HandlerNotFoundException;
import top.misspro.valheimadminsocket.util.AopTargetUtils;
import top.misspro.valheimadminsocket.util.SpringContextUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;

/**
 * @author Evan
 */
@Slf4j
public abstract class ServerActionFactory {

    public static HandlerStruct getProcess(top.misspro.valheimadminsocket.message.Action.Server action) throws HandlerNotFoundException {
        ApplicationContext applicationContext = SpringContextUtil.getApplicationContext();
        Map<String, Object> beanNames = applicationContext.getBeansWithAnnotation(Service.class);

        ArrayList<HandlerStruct> structs = new ArrayList<>();
        for (Object obj : beanNames.values()) {
            Object target = null;
            try {
                target = AopTargetUtils.getTarget(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Method[] methods = target.getClass().getDeclaredMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(Action.class)) {
                    Action declaredAnnotation = method.getDeclaredAnnotation(Action.class);
                    if (action.getCode() == declaredAnnotation.ACTION().getCode()) {
                        structs.add(new HandlerStruct(obj,method));
                    }
                }
            }
        }
        if (structs.isEmpty()) {
            throw new HandlerNotFoundException("未找到匹配的处理方法");
        }
        if (structs.size() > 1) {
            log.warn("存在多个处理：" + action.name() + "处理方法，请检查所有@Handler处理器！");
        }
        return structs.get(0);

    }
}
